/* ==================================================================== *
 *
 * This file is part of Mapics Framework.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @author Andrey Cherkashin <action.open@gmail.com>
 *
 * ==================================================================== */

/**
 * Abstract class to make map layer
 *
 * @package mapics
 * @static
 * @author Andrey Cherkashin <action.open@gmail.com>
 */
mapics.MapLayer = function()
{
    
};

/**
 * Map layer constants
 *   + Types
 *   + State flags
 */
mapics.MapLayer.TYPE_MAP        = 1;
mapics.MapLayer.TYPE_SATELLITE  = 2;
mapics.MapLayer.TYPE_HYBRID     = 3;

mapics.MapLayer.STATE_POSITION  = 1;
mapics.MapLayer.STATE_TYPE      = 2;
mapics.MapLayer.STATE_OVERLAYS  = 4;
mapics.MapLayer.STATE_EVENTS    = 8;
mapics.MapLayer.STATE_FULL      = 255;

/**
 * Return div where map is rendering on
 *
 * @return HTMLObject
 */
mapics.MapLayer.prototype.getDiv = function() {
    return this.m_MapDiv;
};

/**
 * Returns current state of this map
 *
 * @see mapics.MapLayer constants
 * 
 * @param flags (int) What to save in state
 *
 * @return mapics.MapLayerState
 */
mapics.MapLayer.prototype.getState = function(flags)
{
    if( flags == null ) {
        flags = mapics.MapLayer.STATE_FULL;
    }

    var stateData = {};

    if( flags & mapics.MapLayer.STATE_POSITION ) {
        stateData['center'] = this.getCenter();
        stateData['zoom']   = this.getZoom();
    }

    if( flags & mapics.MapLayer.STATE_TYPE  ) {
        stateData['type'] = this.getType();
    }

    if( flags & mapics.MapLayer.STATE_OVERLAYS ) {
        stateData['overlays'] = this.getOverlays();
    }

    if( flags & mapics.MapLayer.STATE_EVENTS ) {
        stateData['events'] = this.getEventListeners();
    }

    return new mapics.MapLayerState(stateData);
};

/**
 * Sets current state of this map
 *
 * @param state (mapics.MapLayerState) New map state
 *
 * @return mapics.MapLayer
 */
mapics.MapLayer.prototype.setState = function(state)
{
    if( state.hasCenter() ) {
        this.setCenter( state.getCenter() );
    }
    
    if( state.hasZoom() ) {
        this.setZoom( state.getZoom() );
    }

    if( state.hasType() ) {
        this.setType( state.getType() );
    }

    if( state.hasOverlays() ) {
        this.setOverlays( state.getOverlays() );
    }

    if( state.hasEventListeners() ) {
        this.setEventListeners( state.getEventListeners() );
    }
};

/**
 * Returns current map event listeners array
 *
 * @return Array<mapics.MapEventListener>
 */
mapics.MapLayer.prototype.getEventListeners = function() {
    return this.m_Listeners;
};

/**
 * Sets current map event listeners array
 *
 * @param mapEventListeners (Array<mapics.MapEventListener>)
 *
 * @return mapics.MapLayer
 */
mapics.MapLayer.prototype.setEventListeners = function(mapEventListeners)
{
    var i, max;

    for(i = 0, max = this.m_Listeners.length; i < max; i++) {
        this.removeListener(this.m_Listeners[i]);
    }

    for(i = 0, max = mapEventListeners.length; i < max; i++) {
        this.addListener(
            mapEventListeners[i].getEventName(),
            mapEventListeners[i].getHandler()
        );
    }
};

/**
 * Returns current overlays of this map layer
 *
 * @return {
 *     1: (Array) Array of mapics.MapObject
 *     ...
 *     n: (Array)
 * }
 */
mapics.MapLayer.prototype.getOverlays = function()
{
    var result = {};

    for( var key in this.m_Overlays ) {
        result[key] = this.m_Overlays[key].getMapObjects();
    }

    return result;
};

/**
 * Sets current overlays of this map layer
 *
 * @param mapOverlays {
 *     1: (Array) Array of mapics.MapObject
 *     ...
 *     n: (Array)
 * }
 *
 * @return mapics.MapLayerYandex
 */
mapics.MapLayer.prototype.setOverlays = function(mapOverlays)
{
    for( var key in mapOverlays ) {
        this.getOverlay(key).setMapObjects( mapOverlays[key] );
    }

    return this;
};